역참조 조인으로 인해 발생하는 성능이슈는 MongoDB에서만 발생하는 문제인건가요, 관계형 데이터베이스에서도 충분히 발생할 수 있는 문제인가요
Chat GPT 4o Answer
매우 좋은 질문입니다. 결론부터 말하면:
✅ 역참조 조인으로 인한 성능 이슈는 MongoDB에서 특히 자주 발생하지만, 관계형 데이터베이스(RDB)에서도 충분히 발생할 수 있습니다. 다만, 두 시스템은 동작 방식과 최적화 전략이 다르기 때문에 문제가 발생하는 방식과 빈도는 다릅니다.
1. 📚 역참조(Reverse Lookup)란?
역참조란 “상위 엔티티가 하위 엔티티에 의해 참조되었는지”를 조회하는 것입니다.
예:
- 정방향: Ticket → TicketPlan (FK 사용)
- 역방향: TicketPlan → Ticket (FK를 가진 쪽을 역으로 찾음)
2. MongoDB에서의 역참조 성능 이슈
MongoDB의 제약:
- MongoDB는 도큐먼트지향 구조이기 때문에 Join이 불가능하며, $lookup을 통해서야만 “조인처럼” 사용할 수 있습니다.
- $lookup은 기본적으로 Nested Loop Join으로 동작합니다 → 매우 느릴 수 있음
- 역참조 + $match 조합은 아래 순서로 처리됨:
- 모든 ticketPlan을 가져옴
- 각 ticketPlan에 대해 ticket을 join (
ticketPlan._id == ticket.ticketPlan
) - 그 결과에 대해 $match 실행
결과:
- $lookup 이전에 필터링을 하지 못하므로, 조인 비용이 N×M으로 커질 수 있음
- 대규모 컬렉션에서는 타임아웃 혹은 수백 초의 응답시간이 흔하게 발생
3. RDB(Relational DB)에서는 어떤가?
관계형 DB의 Join 처리 방식:
- PostgreSQL, MySQL, Oracle 등은 조인을 위한 다양한 Join 알고리즘을 갖추고 있습니다:
- Nested Loop Join
- Hash Join
- Merge Join
- 그리고 통계 기반 옵티마이저가 최적의 실행 계획을 선택합니다.
- 외래 키(FK) + 인덱스가 있다면, 역참조도 매우 빠르게 수행 가능
하지만! 다음과 같은 경우에는 역참조도 RDB에서 병목이 될 수 있습니다:
상황 | 설명 |
---|---|
❌ 역참조 대상 컬럼에 인덱스 없음 | Join 시 전체 스캔 발생 |
❌ Join된 컬럼이 매우 많음 (JOIN BLOAT) | 읽어야 하는 데이터가 많아져서 느림 |
❌ Join 이후 WHERE 조건이 비효율적 | Filter가 늦게 걸림 |
❌ 복잡한 서브쿼리 안에 Join 존재 | 옵티마이저가 잘못된 실행 계획 선택 가능 |
4. ✅ 요약 정리
항목 | MongoDB | RDB (PostgreSQL, MySQL 등) |
---|---|---|
Join 지원 | 제한적 ($lookup) | 네이티브 지원 |
역참조 처리 방식 | 전부 스캔 후 필터링 (비효율) | 옵티마이저가 계획 수립 |
성능 이슈 빈도 | 매우 자주 발생 | 인덱스/설계 문제시 발생 |
해결 방법 | 정방향 조회, denormalization | 인덱스 튜닝, 실행 계획 분석 |
5. 💡 권장 전략 (두 시스템 공통)
전략 | 설명 |
---|---|
✅ 정방향 조회 우선 | 항상 FK를 가진 엔티티에서 조회 시작 |
✅ 인덱스 활용 | Join 대상 컬럼에 인덱스 필요 |
✅ 조인 최소화 | 정말 필요한 관계만 join |
✅ 조회 방향 정비 | 역방향 조회가 많다면 설계 점검 |
✅ 읽기모델 분리 (CQRS) | MongoDB에서는 projection 또는 denormalization 사용 |